package cn.techjc;

import com.jfinal.kit.PropKit;
import com.trilead.ssh2.Connection;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class SSHService {

    private static Map<Integer,Status> cache = new LinkedHashMap<>();

    public static Map<Integer, Status> getCache() {
        return cache;
    }

    static {
        for(int i = 6001 ;i <= 6006 ; i++){
            Status status = new Status();
            status.setUrl("http://"+i+".techjc.cc");
            cache.put(i,status);
        }
    }

    private static Connection connection = null;

    private void set600xOn(int port){
         cache.get(port).setOn(true);
    }

    private void set600xInfo(int port,String info){
        cache.get(port).setInfo(info);
    }

    private void set600xOff(int port){
        cache.get(port).setOn(false);
    }

    private boolean is600xOn(int port){
        return cache.get(port).isOn();
    }

    public Map<String,Object> startForwardRemote(String localIP , int localPort, int remotePort){
        Map<String,Object> map = new HashMap<>();
        //todo:校验ip是否合法
        //校验port是否合法
        if(remotePort !=6001 && remotePort !=6002 && remotePort !=6003 && remotePort !=6004 && remotePort !=6005 && remotePort !=6006 ){
            map.put("code","-1");
            map.put("message","转发端口错误，必须是6001-6006");
            return map;
        }
        //校验端口是否被占用
        if(is600xOn(remotePort)){
            map.put("code","-2");
            map.put("message","端口："+remotePort+"被其他人使用");
            return map;
        }

        PropKit.use("a_little_config.txt");
        String userName = PropKit.get("sshUserName").trim();
        String password = PropKit.get("sshPassword").trim();
        String serverIP = PropKit.get("serverIP").trim();
        int serverPort = PropKit.getInt("serverPort");
        //开启端口转发
        try {
            if(connection == null){
                connection = new Connection(serverIP,serverPort);
                connection.connect();
                if(!connection.authenticateWithPassword(userName,password)){
                    map.put("code","-3");
                    map.put("message","SSH授权失败");
                    connection = null;
                }
            }

            connection.requestRemotePortForwarding("0.0.0.0",remotePort,localIP,localPort);
            //开启端口占用状态
            set600xOn(remotePort);
            set600xInfo(remotePort,localIP+":"+localPort);
            map.put("code","1");
            map.put("message","端口"+remotePort+"转发成功");
        } catch (IOException e) {
            e.printStackTrace();
            map.put("code","-10");
            map.put("message",e.getMessage());
        }
        return map;
    }

    public Map<String,Object> shutdownForwardRemote(int remotePort){
        Map<String,Object> map = new HashMap<>();
        //todo:校验ip是否合法
        //校验port是否合法
        if(remotePort !=6001 && remotePort !=6002 && remotePort !=6003 && remotePort !=6004 && remotePort !=6005 && remotePort !=6006 ){
            map.put("code","-1");
            map.put("message","转发端口错误，必须是6001-6006");
        }
        //校验端口是否被占用
        if(!is600xOn(remotePort)){
            map.put("code","-2");
            map.put("message","端口："+remotePort+"没有被使用，无需关闭");
        }

        PropKit.use("a_little_config.txt");
        String userName = PropKit.get("sshUserName").trim();
        String password = PropKit.get("sshPassword").trim();
        String serverIP = PropKit.get("serverIP").trim();
        int serverPort = PropKit.getInt("serverPort");
        //开启端口转发
        try {
            if(connection == null){
                connection = new Connection(serverIP,serverPort);
                connection.connect();
                if(connection.authenticateWithPassword(userName,password)){
                    map.put("code","-3");
                    map.put("message","SSH授权失败");
                    connection = null;
                }
            }
            connection.cancelRemotePortForwarding(remotePort);
            //开启端口占用状态
            set600xOff(remotePort);
            set600xInfo(remotePort,"");
            map.put("code","1");
            map.put("message","端口"+remotePort+"关闭转发成功");
        } catch (IOException e) {
            e.printStackTrace();
            map.put("code","-10");
            map.put("message",e.getMessage());
        }
        return map;
    }

    public Map<String,Object> resetConnection(){
        Map<String,Object> map = new HashMap<>();
        if(connection !=null){
            connection.close();
            connection = null;
            for(Map.Entry<Integer,Status> entry:cache.entrySet()){
                entry.getValue().setInfo("");
                entry.getValue().setOn(false);
            }
            map.put("code","1");
            map.put("message","所有连接重置成功");
        }else {
            map.put("code","-1");
            map.put("message","未建立连接无需重置");
        }
        return map;
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        SSHService obj = new SSHService();
        System.out.println(obj.startForwardRemote("192.168.1.101",80,6001));
        Thread.sleep(1000*600);
    }
}
